package com.sky.aspect;

import com.sky.annotation.AutoFill;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Aspect
@Slf4j
@Component
public class AutoFillClass {

//    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
//    public void autoFillPointcut() {
//    }

    // 前置通知，在方法执行前执行 自动填充功能
//    @Before("autoFillPointcut()")
//    public void autoFill(JoinPoint joinPoint) {
//        // 获取当前被拦截的方法上注解的属性值
//        MethodSignature signature = (MethodSignature) joinPoint.getSignature(); //获取当前被拦截的方法标签
//        AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class); //获取当前被拦截的方法上的注解
//        OperationType operationType = autoFill.value(); //获取注解的属性值
//
//        // 获取当前被拦截的方法的参数
//        Object[] args = joinPoint.getArgs();
//        if (args == null || args.length == 0) {
//            return;
//        }
//
//        Object entity = args[0];
//
//        switch (operationType) {
//            case INSERT:
//                try {
//                    Long currentId = BaseContext.getCurrentId();
//                    entity.getClass().getDeclaredMethod("setCreateUser", Long.class).invoke(entity, currentId);
//                    entity.getClass().getDeclaredMethod("setCreateTime", java.time.LocalDateTime.class)
//                            .invoke(entity, java.time.LocalDateTime.now());
//                    // 修改操作
//                    entity.getClass().getDeclaredMethod("setUpdateUser", Long.class).invoke(entity, currentId);
//                    entity.getClass().getDeclaredMethod("setUpdateTime", java.time.LocalDateTime.class)
//                            .invoke(entity, java.time.LocalDateTime.now());
//                } catch (Exception e) {
//                    //当前线程中不存在id
//                    return;
//                }
//                break;
//            case UPDATE:
//                try {
//                    Long currentId = BaseContext.getCurrentId();
//                    // 修改操作
//                    entity.getClass().getDeclaredMethod("setUpdateUser", Long.class).invoke(entity, currentId);
//                    entity.getClass().getDeclaredMethod("setUpdateTime", java.time.LocalDateTime.class)
//                            .invoke(entity, java.time.LocalDateTime.now());
//                } catch (Exception e) {
//                    //当前线程中不存在id
//                    return;
//                }
//                break;
//        }
//
//    }

    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    public void autoFillPointcut() {
    }

    @Before("autoFillPointcut()")
    public void autoFill(JoinPoint joinPoint) {

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        AutoFill annotation = signature.getMethod().getAnnotation(AutoFill.class);

        Object[] args = joinPoint.getArgs();

        if (args == null || args.length == 0) {
            return;
        }

        Object arg = args[0];

        LocalDateTime now = LocalDateTime.now();

        if (annotation.value() == OperationType.INSERT) {
//            for (Object arg : args) {
            try {
                arg.getClass().getDeclaredMethod("setCreateUser", Long.class)
                        .invoke(arg, BaseContext.getCurrentId());
                arg.getClass().getDeclaredMethod("setUpdateUser", Long.class)
                        .invoke(arg, BaseContext.getCurrentId());
                arg.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class)
                        .invoke(arg, now);
                arg.getClass().getDeclaredMethod("setCreateTime", LocalDateTime.class)
                        .invoke(arg, now);
            } catch (Exception e) {
                log.info("aop调用异常 {}", e.getMessage());
                throw new RuntimeException(e);
//                }
//                arg.getClass().getDeclaredMethod("setCreateUser", Long.class).invoke(entity, currentId);
            }
        } else if (annotation.value() == OperationType.UPDATE) {
//            for (Object arg : args) {
            try {
                arg.getClass().getDeclaredMethod("setUpdateUser", Long.class)
                        .invoke(arg, BaseContext.getCurrentId());
                arg.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class)
                        .invoke(arg, now);
            } catch (Exception e) {
                throw new RuntimeException(e);
//                }
            }
        }
        log.info(" aop 被调用 ");
    }
}

